﻿using UnityEngine;
using System.Collections.Generic;
using ProtoBuf.Message;
using System;
using UI;

namespace Room
{
    public class NetUnionFightBattle : NetUnionFightBase
    {
        public int camp;
        public long curTime;
        public long totalTime;
        public UnionFightState state;

        public List<InstUFUnion> unionInfos = new List<InstUFUnion>();

        Dictionary<long, InstUFBuff> buffs = new Dictionary<long, InstUFBuff>();
        Dictionary<long, List<long>> buffTarget = new Dictionary<long, List<long>>();

        Dictionary<long, InstUFTotem> totems = new Dictionary<long, InstUFTotem>();

        public NetUnionFightBattle(RoomUnionFight unionFight, RoomCharactorManager mgr, RoomNetUnionFight net)
            : base(unionFight, mgr, net)
        {
        }

        public override void Enter()
        {
            base.Enter();
            buffs.Clear();
        }

        public override void Leave()
        {
            base.Leave();
            buffs.Clear();
        }


        public override void Tick()
        {
            base.Tick();
        }

        public override void ClearCharactorData(long uuid)
        {
            base.ClearCharactorData(uuid);
            List<long> willDeleteBuff = new List<long>();
            foreach (var kvp in buffTarget)
            {
                var buffId = kvp.Key;
                var list = kvp.Value;
                if (list != null && list.Contains(uuid))
                {
                    if (list.Count == 1)
                    {
                        willDeleteBuff.Add(buffId);
                    }
                }
            }

            foreach (var buffId in willDeleteBuff)
            {
                buffTarget.Remove(buffId);
                buffs.Remove(buffId);
            }

            if (totems.ContainsKey(uuid))
            {
                totems.Remove(uuid);
            }
        }

        /// <summary>
        /// 开始进入战场
        /// </summary>
        /// <param name="msg"></param>
        public void UnionFightEnter(SCUnionFightTransfer msg)
        {
            StaticData.unionFightData.SetFightData(msg);
            #region 初始化静态建筑
            foreach (var factory in msg.factoryInfos)
            {
                net.netChariotFactory.ChariotFactoryRefresh(factory);
            }

            foreach (var tower in msg.towerInfos)
            {
                net.netTower.TowerRefresh(tower);
            }

            foreach (var gate in msg.gateInfos)
            {
                net.netGate.GateRefresh(gate);
            }

            foreach (var revive in msg.revivePointInfos)
            {
                net.netRevivePoint.RevivePointRefresh(revive);
            }

            foreach (var camp in msg.baseCampInfos)
            {
                net.netCamp.BaseCampRefresh(camp);
            }
            #endregion

            unionInfos = msg.unionInfos;

            charactorManager.CreateUnionSelfPlayer(msg.player);
            net.netActor.players[msg.player.guid] = msg.player;

            UpdateHp(msg.player.fightInfo);

            this.camp = msg.player.camp;

#if UNITY_EDITOR
            var charactor = charactorManager.GetSelfCharactor();
            charactor.Camp = msg.player.camp;
#endif
            Debug.Log("[DEBUG] init postion: " + msg.playerPos.x + "," + msg.playerPos.y + "," + msg.playerPos.z);

            postions[msg.player.guid] = new Vector3(msg.playerPos.x, msg.playerPos.y, msg.playerPos.z);
            UpdatePosition(msg.player.guid, postions[msg.player.guid]);

            totalTime = msg.totalTime;
            curTime = msg.leftTime;
            state = (UnionFightState)msg.state;
            UpdateState(msg.player.guid, msg.player.state);

            PlayStand();
            //GateLogic();
            GetUI().Refresh();
        }

        /// <summary>
        /// 刷新建筑物
        /// </summary>
        /// <param name="msg"></param>
        public void BattleBuildingRefresh(SCUFBuildingRefresh msg)
        {
            #region 初始化静态建筑
            foreach (var factory in msg.factoryInfos)
            {
                net.netChariotFactory.ChariotFactoryRefresh(factory);
            }

            foreach (var tower in msg.towerInfos)
            {
                net.netTower.TowerRefresh(tower);
            }

            foreach (var gate in msg.gateInfos)
            {
                net.netGate.GateRefresh(gate);
            }

            foreach (var revive in msg.pointInfos)
            {
                net.netRevivePoint.RevivePointRefresh(revive);
            }

            foreach (var camp in msg.baseCampInfos)
            {
                net.netCamp.BaseCampRefresh(camp);
            }
            #endregion

            unionInfos = msg.unionInfos;
            PlayStand();
        }

        /// <summary>
        /// 刷新战场状态
        /// </summary>
        /// <param name="msg"></param>
        public void UnionFightState(SCUnionFightUpdateState msg)
        {
            StaticData.unionFightData.SetFightData(msg);
            totalTime = msg.totalTime;
            curTime = msg.leftTime;
            state = (UnionFightState)msg.state;

            //GateLogic();
            GetUI().Refresh();
        }

        public void CreateCountDown()
        {
            var selfAi = charactorManager.GetSelfCharactor().ai as RCAIUnionSelf;
            selfAi.CreateCountDown();
        }

        /// <summary>
        /// 战斗结果
        /// </summary>
        public void UnionFightResult(SCUnionFightResult msg)
        {
            int winCamp = 0;
            foreach (var union in unionInfos)
            {
                if (union.unionId == msg.result.winUnionId)
                    winCamp = union.camp;
            }

            var camps = net.netCamp.baseCamps;
            foreach (var _cmap in camps)
            {
                var charactor = GetCharactor(_cmap.Key + "");
                var ai = charactor.ai as RCAIBaseCamp;
                if (ai.dictData.Camp != winCamp)
                {
                    ai.PlayDie();
                }
            }

            GetUI().Refresh();
            GetUI().OpenBattleResultPage(winCamp, msg.result);
        }

        /// <summary>
        /// 收到资源
        /// </summary>
        /// <param name="msg"></param>
        public void UnionResourceRefresh(SCUFCampResourceUpdate msg)
        {
            for (int i = 0; i < unionInfos.Count; i++)
            {
                unionInfos[i].unionResource = msg.resource;
            }
            var res = GetSelfCampUnionResourseNum();

            GetUI().SetUnionResNum(res);
        }

        //获取己方公会资源数目
        public int GetSelfCampUnionResourseNum()
        {
            for (int i = 0; i < unionInfos.Count; i++)
            {
                if (unionInfos[i].camp == camp)
                    return (int)unionInfos[i].unionResource.resourceNum;
            }
            return 0;
        }


        public InstUFUnion GetUnionByUnionId(string id)
        {
            for (int i = 0; i < unionInfos.Count; i++)
            {
                if (unionInfos[i].unionId == id)
                    return unionInfos[i];
            }
            Debug.LogError("Union Id Error:" + id);
            return null;
        }

        public InstUFUnion GetUnoin(bool isSelf)
        {
            for (int i = 0; i < unionInfos.Count; i++)
            {
                if (isSelf)
                {
                    if (unionInfos[i].camp == camp)
                        return unionInfos[i];
                }
                else
                {
                    if (unionInfos[i].camp != camp)
                        return unionInfos[i];
                }
            }
            return null;
        }

        void PlayStand()
        {
            foreach (var camp in net.netCamp.baseCamps)
            {
                var charactor = GetCharactor(camp.Key + "");
                var ai = charactor.ai as RCAIBaseCamp;
                ai.PlayStand();
            }
        }

        ///// <summary>
        ///// 门的逻辑
        ///// </summary>
        //void GateLogic()
        //{
        //    if (state == global::UnionFightState.Ready)
        //    {
        //        net.netGate.CloseAllGates();
        //    }
        //    else
        //    {
        //        net.netGate.ResetGates();
        //    }
        //}


        /// <summary>
        /// 刷新UI界面商品list
        /// </summary>
        /// <param name="msg"></param>
        public void BattleProductList(SCUFShopList msg)
        {
            GetUI().shopPage.UpdateItemList(msg.items);
        }

        //个人任务
        public void PlayerMissionList(SCUFPlayerMissionList msg)
        {
            GetUI().taskPage.UpdatePlayerList(msg.missionInfos);
        }
        //公会任务
        public void UnionMissionList(SCUFUnionMissionList msg)
        {
            GetUI().taskPage.UpdateMissionList(msg.missionInfos);
        }
        //红点
        public void MissionPush(SCUFMissionPush msg)
        {
            GetUI().SetRedState(0, true);
            GetUI().SetBattleScore((int)msg.playerFightScore);
        }

        //收到公会喊话
        public void UFTalk(SCUFTalk  msg)
        {
            net.netAnnounce.ReceiveMsg(msg.content);
        }

        public void ReceiveMsg(SCPublicMessage msg)
        {
            net.netAnnounce.ReceiveMsg(msg.pubmsg.msg);
        }
        //打开地图
        public void OpenBigMap()
        {
            GetUI().OpenBigMapPage();
        }

        //战斗记录
        public void FightRecord(SCUFFightRecord msg)
        {
            GetUI().OpenFightRecordPage(msg);
        }

        //记录回放
        public void FightRecordReplay(SCUFFightRecordReplay msg)
        {
            StaticData.curBattleData.SetData(msg);
            ManagerController.Instance.RoomToBattle();
        }

        //会长集结点
        public void LeaderFocus(SCUFLeaderFocus msg)
        {
            if (msg.pos.Count <= 0)
                GetUI().bigMapPage.HideGatherTips();
            else
                GetUI().bigMapPage.ShowGatherTips(msg.pos[0],msg.lastTime);
        }

        //普通玩家集结点
        public void LeaderFocusDisappear(SCUFFocusPointInfo msg)
        {
            if (msg.pos.Count <= 0)
                GetUI().bigMapPage.HideGatherTips();
            else
                GetUI().bigMapPage.ShowGatherTips(msg.pos[0]);
        }

        public void StrenthenBuildingInfo(SCUFStrengthBuildingInfo msg)
        {
            GetUI().buildingPage.UpdateList(msg.infos, msg.optCD);
        }

        public void HookOn(SCUFOnHook msg)
        {
            UnionFightData.IsOnHook = msg.onHook == 1 ? true : false;
            if(!UnionFightData.IsOnHook)
            {
                var charactor = GetCharactor(StaticData.playerData.playerId);
                charactor.StopMove();
                charactor.SetSpeed(net.mainActorSpeed);
            }
        }
        
        public void KickBack(SCUFKickPlayer msg)
        {
#if UNITY_EDITOR
            return;
#endif
            ManagerController.Instance.TrySceneTransfer(ServerScene.Town, Vector3.zero, "", () =>
            {
                var go = GetUI().gameObject;
                go.GetComponent<UIUnionFightRunMap>().Close();
                PageManager.Instance.OpenPage("TownPage", "");
            });
        }

        public void LoadBuff(SCUFElementBuffOn msg)
        {
            for(var i =0;i<msg.targetGuid.Count;++i)
            {
                var uuid = msg.targetGuid[i];
                var charactor = GetCharactor(uuid);
                var ai = charactor.ai as RCAIUnionFightBase;
                
                var buff = msg.buff[i];
                ai.LoadBuff(buff);
                
                var buffId = buff.guid;
                buffs[buffId] = buff;
                if(buffTarget.ContainsKey(buffId))
                {
                    var list = buffTarget[buffId];
                    if(list==null)
                    {
                        list = new List<long>();
                    }
                    else if(!list.Contains(uuid))
                    {
                        list.Add(uuid);
                    }
                }
                else
                {
                    var list = new List<long>();
                    list.Add(uuid);
                    buffTarget[buffId] = list;
                }
            }
        }

        public void UnloadBuff(SCUFElementBuffOff msg)
        {
            List<long> willDelete = new List<long>();
            for(var i=0;i<msg.buffGuid.Count;++i)
            {
                var buffId = msg.buffGuid[i];
                if(buffs.ContainsKey(buffId))
                {
                    var buff = buffs[buffId];
                    if(buffTarget.ContainsKey(buffId))
                    {
                        var targetBuff = buffTarget[buffId];
                        foreach(var item in targetBuff)
                        {
                            var uuid = item ;
                            var charactor = GetCharactor(uuid);
                            if(charactor!=null)
                            {
                                var ai = charactor.ai as RCAIUnionFightBase;
                                if(ai!=null)
                                {
                                    ai.UnloadBuff(buff);
                                }
                            }
                        }
                    }
                }

                willDelete.Add(buffId);
            }

            foreach(var bid in willDelete)
            {
                if(buffs.ContainsKey(bid))
                {
                    buffs.Remove(bid);
                }
                if(buffTarget.ContainsKey(bid))
                {
                    buffTarget.Remove(bid);
                }
            }
            
        }

        /// <summary>
        /// hp tick
        /// </summary>
        /// <param name="msg"></param>
        public void TickHp(SCUFElementTickExport msg)
        {
            for (var i = 0; i < msg.targetGuid.Count; ++i)
            {
                var tUuid = msg.targetGuid[i];
                var sUuid = msg.sourceGuid[i];
                var hp = (float)msg.hpDelta[i];

                var charactor = GetCharactor(tUuid);
                if (charactor != null)
                {
                    var ai = charactor.ai as RCAIUnionFightBase;
                    var src = GetCharactor(sUuid);
                    ai.TickHp(src, hp);
                }

                //如果是玩家,怪物，守卫
                if(net.netActor.players.ContainsKey(tUuid))
                {
                    var player = net.netActor.players[tUuid];
                    var count = player.fightInfo.hpPos.Count;
                    for(int index=0; index < count; index++)
                    {
                        player.fightInfo.hpPos[index] += hp / (float)count;
                    }
                    UpdateHp(player.fightInfo);
                }
                else if(net.netMonster.monsters.ContainsKey(tUuid))
                {
                    var monster = net.netMonster.monsters[tUuid];
                    var count = monster.fightInfo.hpPos.Count;
                    for (int index = 0; index < count; index++)
                    {
                        monster.fightInfo.hpPos[index] += hp / (float)count;
                    }
                    UpdateHp(monster.fightInfo);
                }
                else if(net.netGuard.guards.ContainsKey(tUuid))
                {
                    var guard = net.netGuard.guards[tUuid];
                    var count = guard.fightInfo.hpPos.Count;
                    for (int index = 0; index < count; index++)
                    {
                        guard.fightInfo.hpPos[index] += hp / (float)count;
                    }
                    UpdateHp(guard.fightInfo);
                }
                else if (net.netGate.gates.ContainsKey(tUuid))
                {
                    var gate = net.netGate.gates[tUuid];
                    var maxHp = gate.maxHp;
                    UpdateHp(tUuid,(float)(hp/maxHp));
                }
                //简直物在AI内部处理
                
                UpdateWordTip(tUuid, hp);

            }
        }


        public void TotemRefresh(SCUFTotemCreate msg)
        {
            var totem = msg.totem;
            var uuid = totem.guid;
            var pos = new Vector3(msg.pos.x, msg.pos.y, msg.pos.z);
            

            charactorManager.CreateUnionTotem(msg.totem, pos);
            totems[uuid] = totem;
        }

        public void TotomDestroy(SCUFTotemDestroy msg)
        {
            var uuid = msg.guid;
            DestroyCharactor(uuid);
        }

    }
}
